let Vue

class Store {
  constructor(options) {
    this._mutations = options.mutations
    this._actions = options.actions
    // 相应化处理state
    // this.state = new Vue({
    //   data: options.state
    // })

    // 改进一版 防止修改
    this._vm = new Vue({
      // 加了两个$ vue不会做代理
      data: {
        $$state: options.state
      }
    })

    this._getters = options.getters
    // 绑定上下文为store实例
    this.commit  = this.commit.bind(this)
    this.actions = this.dispatch.bind(this)
  }

  get state() {
    return this._vm._data.$$state
  }

  set state() {
    console.error('state不允许修改')
  }

  // getters方法
  get getters () {
    let result = {}
    Object.getOwnPropertyNames(this._getters).forEach((key) =>{
      result[key] = this._getters[key](this.state)
    })
    return result
  }

  // type mutation
  commit(type, payload) {
    const entry = this._mutations[type]
    if (entry) {
      entry(this.state, payload)
    }
  }

  dispatch(type, payload) {
    const entry = this._actions[type]
    if (entry) {
      entry(this, payload)
    }
  }
}

function install(_vue) {
  Vue = _vue
  Vue.mixin({
    beforeCreate() {
      if (this.$options.store) {
        Vue.prototype.$store = this.$options.store
      }
    }
  })
}

export default {
  Store,
  install
}